package com.library.common.handler;

import com.library.common.annotation.CurrentUser;
import com.library.common.service.TrendInvocationSecurityService;
import com.library.common.service.bo.CurrentLoginUser;
import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;


/**
 * 参数解析器
 *
 * @author: xyh
 * @create: 2023-04-24
 **/
@Log4j2
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Resource
    private TrendInvocationSecurityService trendInvocationSecurityService;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().isAssignableFrom(CurrentLoginUser.class)
                && methodParameter.hasParameterAnnotation(CurrentUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            log.error("当前登录状态过期", HttpStatus.UNAUTHORIZED);
            return new CurrentLoginUser();
        }
        if (authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            //拿到用户名
            CurrentLoginUser loginUser = trendInvocationSecurityService.getCurrentLoginUser(userDetails.getUsername());
            return loginUser;
        }
        return new CurrentLoginUser();
    }

}
